package edu.gatech.doi.spamframework.model;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;

import edu.gatech.doi.spamframework.mapping.MappingAttribute;

public class XMLOperator {
	private String modeldirectory=System.getProperties().getProperty("user.dir")+System.getProperties().getProperty("file.separator")+"models";
	
	private String modeldefaultfilename="personmodel.xml";
	
	private String mappingdirectory;
	
	private String mappingdefaultfilename;
	
	
	public HashMap getModelAttrsFromXML(String filepath)
	{
		HashMap hm=new HashMap();
		/**
		 * XML parser
		 */
		SAXBuilder builder = new SAXBuilder();
       try {
			Document doc = builder.build(filepath);
			Element root = doc.getRootElement();
			/**
			 * attributes,attribute
			 */
//			hm=new HashMap();
			List attrlist=root.getChildren();
			Iterator it=attrlist.iterator();
			while(it.hasNext())
			{
				
				Element attribute=(Element) it.next();
				String attributename=attribute.getChild("attributename").getTextTrim();
				int attributetypeid=Integer.parseInt(attribute.getChild("attributetypeid").getTextTrim());
				String attributetypename=attribute.getChild("attributetypename").getTextTrim();
				String nominalvaluesstr=attribute.getChild("nominalvalues").getTextTrim();
				String dateformat=attribute.getChild("dateformat").getTextTrim();
				String description=attribute.getChild("description").getTextTrim();
				
//				System.out.println("attributename:"+attributename);
//				System.out.println("attributetypeid:"+attributetypeid);
//				System.out.println("attributetypename:"+attributetypename);
//				System.out.println("dateformat:"+dateformat);
//				System.out.println("description:"+description);
				
				ArrayList nominalvalues=new ArrayList();
				if(attributetypeid==2)
				{
					String[] tempstrs=nominalvaluesstr.split(",");
					
					for(int i=0;i<tempstrs.length;i++)
					{
//						System.out.println("nomialvalues:"+tempstrs[i]);
						nominalvalues.add(tempstrs[i].trim());
					}
					
				}
				
				// construct modelattribute hashmap
				ModelAttribute ma=new ModelAttribute(attributename,attributetypeid,attributetypename,nominalvalues,dateformat,description);
			
				hm.put(attributename, ma);
				
			}
	
			
		} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return hm;
	}
	
	public void saveModel2XML(String filepath,HashMap hm)
	{
		File file=new File(filepath);
		if(!file.exists())
		{
			try {
				file.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		else
		{
			file.delete();
			try {
				file.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		Element root = new Element("attributes");
		Iterator iterator=hm.keySet().iterator();
		while(iterator.hasNext())
		{
			ModelAttribute ma=(ModelAttribute) hm.get(iterator.next());
			Element attribute = new Element("attribute");
			 
			Element attributename=new Element("attributename");
			Element attributetypeid=new Element("attributetypeid");
			Element attributetypename=new Element("attributetypename");
			Element nominalvalues=new Element("nominalvalues");
			Element dateformat=new Element("dateformat");
			Element description=new Element("description");
			
			attributename.setText(ma.getAttributeName());
			attributetypeid.setText(String.valueOf(ma.getAttributeTypeId()));
			attributetypename.setText(ma.getAttributeTypeName());
			
			StringBuffer nominalvaluesstr=new StringBuffer();
			if(ma.getAttributeTypeId()==2)
			{
				ArrayList al=ma.getNomialValues();
				Iterator it=al.iterator();
				while(it.hasNext())
				{
					String tempstr=(String) it.next();
					nominalvaluesstr=nominalvaluesstr.append(tempstr+",");
				}
				nominalvaluesstr.deleteCharAt(nominalvaluesstr.lastIndexOf(","));
				
			}
			nominalvalues.setText(nominalvaluesstr.toString());
			
			dateformat.setText(ma.getDateFormat());
			description.setText(ma.getDescription());
			attribute.addContent(attributename);
			attribute.addContent(attributetypeid);
			attribute.addContent(attributetypename);
			attribute.addContent(nominalvalues);
			attribute.addContent(dateformat);
			attribute.addContent(description);
			root.addContent(attribute);
		}

		 

	    System.out.println("XML outputting");

	    Document doc = new Document(root);
	    doc.setBaseURI(filepath);
	    // serialize it onto System.out
	    try {
	      XMLOutputter serializer = new XMLOutputter();
	
	     
	      serializer.output(doc, System.out);
//	      FileWriter fw=new FileWriter(filepath);
//	      BufferedWriter out=new BufferedWriter(fw);
	      FileOutputStream fos       = new FileOutputStream(file);
	      
	      serializer.output(doc, fos);
	      
	    }
	    catch (IOException e) {
	      System.err.println(e);
	    }
	}
	
	public void addModelAttribute(String filepath,ModelAttribute ma)
	{
		HashMap hm=this.getModelAttrsFromXML(filepath);
		hm.put(ma.getAttributeName(), ma);
		this.saveModel2XML(filepath, hm);
	}
	
	public void removeModelAttribute(String filepath,ModelAttribute ma)
	{
		HashMap hm=this.getModelAttrsFromXML(filepath);
		hm.remove(ma.getAttributeName());
		this.saveModel2XML(filepath, hm);
	}
	
	public HashMap getMappingAttrsFromXML(String filepath)
	{
		HashMap hm=null;
		/**
		 * XML parser
		 */
		SAXBuilder builder = new SAXBuilder();
       try {
			Document doc = builder.build(filepath);
			Element root = doc.getRootElement();
			/**
			 * attributes,attribute
			 */
			hm=new HashMap();
			List attrlist=root.getChildren();
			Iterator it=attrlist.iterator();
			while(it.hasNext())
			{
				
				Element attribute=(Element) it.next();
				String attributename=attribute.getChild("attributename").getTextTrim();
				String modelattributename=attribute.getChild("modelattributename").getTextTrim();
				int attributetypeid=Integer.parseInt(attribute.getChild("attributetypeid").getTextTrim());
				String attributetypename=attribute.getChild("attributetypename").getTextTrim();
				String nominalvaluesstr=attribute.getChild("nominalvalues").getTextTrim();
				String dateformat=attribute.getChild("dateformat").getTextTrim();
				String description=attribute.getChild("description").getTextTrim();
				
//				System.out.println("attributename:"+attributename);
//				System.out.println("attributetypeid:"+attributetypeid);
//				System.out.println("attributetypename:"+attributetypename);
//				System.out.println("dateformat:"+dateformat);
//				System.out.println("description:"+description);
				
				ArrayList nominalvalues=new ArrayList();
				if(attributetypeid==2)
				{
					String[] tempstrs=nominalvaluesstr.split(",");
					
					for(int i=0;i<tempstrs.length;i++)
					{
//						System.out.println("nomialvalues:"+tempstrs[i]);
						nominalvalues.add(tempstrs[i].trim());
					}
					
				}
				
				// construct modelattribute hashmap
				MappingAttribute ma=new MappingAttribute(attributename,modelattributename,attributetypeid,attributetypename,nominalvalues,dateformat,description);
				hm.put(attributename, ma);
				
			}
	
			
		} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return hm;
	}
	
	public void saveMapping2XML(String filepath,HashMap hm)
	{
		File file=new File(filepath);
		if(!file.exists())
		{
			try {
				file.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		else
		{
			file.delete();
			try {
				file.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		Element root = new Element("attributes");
		Iterator iterator=hm.keySet().iterator();
		while(iterator.hasNext())
		{
			MappingAttribute ma=(MappingAttribute) hm.get(iterator.next());
			Element attribute = new Element("attribute");
	
			Element attributename=new Element("attributename");
			Element modelattributename=new Element("modelattributename"); 
			Element attributetypeid=new Element("attributetypeid");
			Element attributetypename=new Element("attributetypename");
			Element nominalvalues=new Element("nominalvalues");
			Element dateformat=new Element("dateformat");
			Element description=new Element("description");
			
			attributename.setText(ma.getAttributeName());
			modelattributename.setText(ma.getModelAttributeName());
			attributetypeid.setText(String.valueOf(ma.getAttributeTypeId()));
			attributetypename.setText(ma.getAttributeTypeName());
			
			StringBuffer nominalvaluesstr=new StringBuffer();
			if(ma.getAttributeTypeId()==2)
			{
				ArrayList al=ma.getNomialValues();
				Iterator it=al.iterator();
				while(it.hasNext())
				{
					String tempstr=(String) it.next();
					nominalvaluesstr=nominalvaluesstr.append(tempstr+",");
				}
				nominalvaluesstr.deleteCharAt(nominalvaluesstr.lastIndexOf(","));
				
			}
			nominalvalues.setText(nominalvaluesstr.toString());
			
			dateformat.setText(ma.getDateFormat());
			description.setText(ma.getDescription());
			attribute.addContent(attributename);
			attribute.addContent(modelattributename);
			attribute.addContent(attributetypeid);
			attribute.addContent(attributetypename);
			attribute.addContent(nominalvalues);
			attribute.addContent(dateformat);
			attribute.addContent(description);
			root.addContent(attribute);
		}

		 

	    System.out.println("XML outputting");

	    Document doc = new Document(root);
	    doc.setBaseURI(filepath);
	    // serialize it onto System.out
	    try {
	      XMLOutputter serializer = new XMLOutputter();
	
	     
	      serializer.output(doc, System.out);
//	      FileWriter fw=new FileWriter(filepath);
//	      BufferedWriter out=new BufferedWriter(fw);
	      FileOutputStream fos       = new FileOutputStream(file);
	      
	      serializer.output(doc, fos);
	      
	    }
	    catch (IOException e) {
	      System.err.println(e);
	    }
	}
	
	public void addMappingAttribute(String filepath,ModelAttribute ma)
	{
		HashMap hm=this.getMappingAttrsFromXML(filepath);
		hm.put(ma.getAttributeName(), ma);
		this.saveMapping2XML(filepath, hm);
	}
	
	public void removeMappingAttribute(String filepath,ModelAttribute ma)
	{
		HashMap hm=this.getMappingAttrsFromXML(filepath);
		hm.remove(ma.getAttributeName());
		this.saveMapping2XML(filepath, hm);
	}
	
	public static void main(String [] arg0)
	{
		XMLOperator xmlo=new XMLOperator();
		String filepath=xmlo.modeldirectory+System.getProperties().getProperty("file.separator")+xmlo.modeldefaultfilename;
		HashMap hm=xmlo.getModelAttrsFromXML(filepath);
		String filepath1=xmlo.modeldirectory+System.getProperties().getProperty("file.separator")+"testperson.xml";
		xmlo.saveModel2XML(filepath1, hm);
		
	}
	
}
